<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta myself="lanfilesearch/templates/index.html" >
    <title>服务器检索系统</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        :root {
            --primary-color: #3a7bd5;
            --primary-light: #5b9ae9;
            --primary-dark: #2a5da6;
            --secondary-color: #2a9d8f;
            --accent-color: #e76f51;
            --background-light: #f8fafc;
            --background-dark: #0f172a;
            --text-dark: #1e293b;
            --text-light: #64748b;
            --border-color: #e2e8f0;
            --card-bg: #ffffff;
            --success-color: #10b981;
            --warning-color: #f59e0b;
            --error-color: #ef4444;
            --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.05);
            --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.08);
            --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
            --transition: all 0.3s ease;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
            line-height: 1.6;
            background: linear-gradient(135deg, var(--background-light) 0%, #e6f0ff 100%);
            color: var(--text-dark);
            min-height: 100vh;
            padding: 30px 20px;
            background-attachment: fixed;
        }

        .container {
            max-width: 1000px;
            margin: 0 auto;
            background: var(--card-bg);
            padding: 30px;
            border-radius: 16px;
            box-shadow: var(--shadow-lg);
            position: relative;
            overflow: hidden;
        }

        .container::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 5px;
            background: linear-gradient(90deg, var(--primary-color), var(--secondary-color), var(--accent-color));
        }

        .header {
            text-align: center;
            margin-bottom: 30px;
            position: relative;
        }

        .header h1 {
            font-size: 2.2rem;
            color: var(--primary-dark);
            margin-bottom: 8px;
            font-weight: 700;
            background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            display: inline-block;
        }

        .header p {
            color: var(--text-light);
            font-size: 1.1rem;
            max-width: 600px;
            margin: 0 auto;
        }

        .search-section {
            background: rgba(255, 255, 255, 0.7);
            backdrop-filter: blur(10px);
            border-radius: 12px;
            padding: 25px;
            margin-bottom: 30px;
            box-shadow: var(--shadow-sm);
            border: 1px solid var(--border-color);
        }

        .search-box {
            display: flex;
            margin-bottom: 20px;
            position: relative;
        }

        .search-input {
            flex: 1;
            padding: 16px 20px;
            font-size: 16px;
            border: 2px solid var(--border-color);
            border-radius: 10px 0 0 10px;
            background: white;
            transition: var(--transition);
            box-shadow: var(--shadow-sm);
        }

        .search-input:focus {
            outline: none;
            border-color: var(--primary-light);
            box-shadow: 0 0 0 3px rgba(58, 123, 213, 0.15);
        }

        .search-btn {
            padding: 0 28px;
            background: linear-gradient(135deg, var(--primary-color), var(--primary-dark));
            color: white;
            border: none;
            border-radius: 0 10px 10px 0;
            cursor: pointer;
            font-size: 16px;
            font-weight: 600;
            transition: var(--transition);
            box-shadow: var(--shadow-sm);
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .search-btn:hover {
            background: linear-gradient(135deg, var(--primary-light), var(--primary-color));
            transform: translateY(-2px);
            box-shadow: var(--shadow-md);
        }

        .search-btn:active {
            transform: translateY(0);
        }

        .search-type-toggle {
            display: flex;
            background: var(--border-color);
            border-radius: 50px;
            padding: 5px;
            margin-bottom: 20px;
            max-width: 400px;
            margin: 0 auto 25px;
        }

        .search-type-btn {
            flex: 1;
            text-align: center;
            padding: 12px 20px;
            background: transparent;
            border: none;
            border-radius: 50px;
            cursor: pointer;
            font-size: 15px;
            font-weight: 600;
            transition: var(--transition);
            color: var(--text-light);
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
        }

        .search-type-btn.active {
            background: white;
            color: var(--primary-color);
            box-shadow: var(--shadow-sm);
        }

        .file-controls {
            background: rgba(255, 255, 255, 0.7);
            border-radius: 12px;
            padding: 20px;
            margin-top: 20px;
            box-shadow: var(--shadow-sm);
            border: 1px solid var(--border-color);
        }

        .file-filter {
            display: flex;
            flex-wrap: wrap;
            gap: 12px;
            margin-bottom: 20px;
        }

        .filter-btn {
            padding: 10px 18px;
            background: white;
            border: 1px solid var(--border-color);
            border-radius: 50px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            transition: var(--transition);
            display: flex;
            align-items: center;
            gap: 6px;
            box-shadow: var(--shadow-sm);
        }

        .filter-btn:hover {
            border-color: var(--primary-light);
        }

        .filter-btn.active {
            background: var(--primary-color);
            color: white;
            border-color: var(--primary-color);
            box-shadow: 0 4px 6px rgba(58, 123, 213, 0.2);
        }

        .sort-controls {
            display: flex;
            align-items: center;
            flex-wrap: wrap;
            gap: 15px;
        }

        .sort-label {
            font-size: 15px;
            color: var(--text-light);
            font-weight: 500;
        }

        .sort-select {
            padding: 10px 15px;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            background: white;
            font-size: 14px;
            transition: var(--transition);
            box-shadow: var(--shadow-sm);
        }

        .sort-select:focus {
            outline: none;
            border-color: var(--primary-light);
        }

        .sort-order {
            display: flex;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            overflow: hidden;
            background: white;
            box-shadow: var(--shadow-sm);
        }

        .sort-order-btn {
            padding: 10px 16px;
            background: white;
            border: none;
            cursor: pointer;
            font-size: 14px;
            transition: var(--transition);
            display: flex;
            align-items: center;
            gap: 5px;
        }

        .sort-order-btn:first-child {
            border-right: 1px solid var(--border-color);
        }

        .sort-order-btn.active {
            background: var(--primary-light);
            color: white;
        }

        .result-stats {
            margin: 20px 0;
            font-size: 15px;
            color: var(--text-light);
            padding: 12px 0;
            border-bottom: 1px solid var(--border-color);
            display: flex;
            justify-content: space-between;
        }

        .result-list {
            margin-top: 20px;
        }

        .result-item {
            padding: 25px;
            border: 1px solid var(--border-color);
            border-radius: 12px;
            margin-bottom: 20px;
            background: white;
            transition: var(--transition);
            position: relative;
            overflow: hidden;
            box-shadow: var(--shadow-sm);
        }

        .result-item:hover {
            transform: translateY(-3px);
            box-shadow: var(--shadow-md);
            border-color: var(--primary-light);
        }

        .result-item h3 {
            margin-top: 0;
            color: var(--primary-dark);
            font-size: 1.3rem;
            margin-bottom: 12px;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .result-item h3 i {
            color: var(--primary-color);
            font-size: 1.2em;
        }

        .highlight-section {
            margin-bottom: 15px;
            padding: 15px;
            background: rgba(235, 245, 255, 0.5);
            border-radius: 8px;
            border-left: 3px solid var(--primary-color);
            font-size: 15px;
            line-height: 1.7;
        }

        .highlight-section em, .full-content em {
            background-color: #fff9c4;
            font-style: normal;
            padding: 0 3px;
            border-radius: 3px;
        }

        .file-meta {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin: 15px 0;
            color: var(--text-light);
            font-size: 14px;
        }

        .meta-item {
            display: flex;
            align-items: center;
            gap: 6px;
        }

        .toggle-button-wrapper {
            text-align: right;
            margin-top: 10px;
        }

        .expand-toggle {
            background: none;
            border: none;
            color: var(--primary-color);
            font-size: 14px;
            cursor: pointer;
            font-weight: 600;
            display: inline-flex;
            align-items: center;
            gap: 5px;
            transition: var(--transition);
            padding: 5px 10px;
            border-radius: 6px;
        }

        .expand-toggle:hover {
            background: rgba(58, 123, 213, 0.1);
        }

        .full-content-container {
            overflow: hidden;
            transition: max-height 0.4s ease-out;
            max-height: 0;
        }

        .full-content-container.expanded {
            max-height: 500px;
        }

        .full-content {
            display: none;
            white-space: pre-wrap;
            margin-top: 15px;
            padding: 20px;
            background: #f8fafc;
            border-radius: 8px;
            max-height: 300px;
            overflow-y: auto;
            font-size: 14px;
            line-height: 1.8;
            border: 1px solid var(--border-color);
        }

        .full-content-container.expanded .full-content {
            display: block;
        }

        .file-result-item {
            padding: 20px;
            border: 1px solid var(--border-color);
            border-radius: 12px;
            margin-bottom: 20px;
            background: white;
            transition: var(--transition);
            position: relative;
            overflow: hidden;
            box-shadow: var(--shadow-sm);
        }

        .file-result-item:hover {
            transform: translateY(-3px);
            box-shadow: var(--shadow-md);
            border-color: var(--primary-light);
        }

        .file-result-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
        }

        .file-result-title {
            margin: 0;
            color: var(--primary-dark);
            font-size: 1.2rem;
            display: flex;
            align-items: center;
            gap: 12px;
            font-weight: 600;
        }

        .file-icon {
            font-size: 1.4em;
            width: 40px;
            height: 40px;
            border-radius: 10px;
            background: rgba(58, 123, 213, 0.1);
            display: flex;
            align-items: center;
            justify-content: center;
            color: var(--primary-color);
        }

        .file-tag {
            display: inline-block;
            padding: 6px 14px;
            background: rgba(42, 157, 143, 0.1);
            border-radius: 50px;
            color: var(--secondary-color);
            font-size: 13px;
            font-weight: 600;
        }

        .file-path {
            word-break: break-all;
            margin: 12px 0;
            padding: 12px;
            background: #f8fafc;
            border-radius: 8px;
            font-family: 'SF Mono', monospace;
            font-size: 13px;
            border: 1px dashed var(--border-color);
        }

        .load-more {
            text-align: center;
            margin-top: 30px;
            display: none;
        }

        .load-more-btn {
            margin: 0 auto;
            padding: 12px 35px;
            background: linear-gradient(135deg, var(--primary-color), var(--primary-dark));
            color: white;
            border: none;
            border-radius: 50px;
            cursor: pointer;
            font-size: 16px;
            font-weight: 600;
            transition: var(--transition);
            display: inline-flex;
            align-items: center;
            gap: 8px;
            box-shadow: var(--shadow-md);
        }

        .load-more-btn:hover {
            background: linear-gradient(135deg, var(--primary-light), var(--primary-color));
            transform: translateY(-3px);
            box-shadow: 0 6px 12px rgba(58, 123, 213, 0.25);
        }

        .load-more-btn:active {
            transform: translateY(0);
        }

        .load-more-btn:disabled {
            background: #cbd5e1;
            cursor: not-allowed;
            transform: none;
            box-shadow: none;
        }

        .timeout-message {
            color: var(--error-color);
            background-color: #ffebee;
            padding: 20px;
            border-radius: 8px;
            margin: 25px 0;
            text-align: center;
            border-left: 4px solid var(--error-color);
        }

        .retry-btn {
            margin-top: 15px;
            padding: 10px 20px;
            background: var(--error-color);
            color: white;
            border: none;
            border-radius: 50px;
            cursor: pointer;
            font-weight: 600;
            transition: var(--transition);
        }

        .retry-btn:hover {
            background: #dc2626;
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(239, 68, 68, 0.2);
        }

        .footer {
            text-align: center;
            margin-top: 40px;
            padding-top: 20px;
            border-top: 1px solid var(--border-color);
            color: var(--text-light);
            font-size: 13px;
        }

        .duplicate-files-section {
            margin-top: 15px;
        }
        
        .duplicate-toggle {
            background: none;
            border: none;
            color: var(--primary-color);
            font-size: 14px;
            cursor: pointer;
            font-weight: 600;
            display: inline-flex;
            align-items: center;
            gap: 5px;
            transition: var(--transition);
            padding: 5px 10px;
            border-radius: 6px;
            margin-bottom: 10px;
        }
        
        .duplicate-toggle:hover {
            background: rgba(58, 123, 213, 0.1);
        }
        
        .duplicate-list {
            display: none;
            padding: 12px;
            background: #f8fafc;
            border-radius: 8px;
            border: 1px solid var(--border-color);
            margin-top: 10px;
        }
        
        .duplicate-list.expanded {
            display: block;
        }
        
        .duplicate-list ol {
            padding-left: 25px;
            margin: 0;
        }
        
        .duplicate-list li {
            padding: 5px 0;
            word-break: break-all;
            font-family: 'SF Mono', monospace;
            font-size: 13px;
        }
        
        .no-duplicates {
            color: var(--text-light);
            font-style: italic;
        }

        .footer p {
            margin: 5px 0;
        }

        .system-tag {
            display: inline-block;
            background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
            color: white;
            padding: 4px 12px;
            border-radius: 50px;
            font-size: 12px;
            font-weight: 600;
            margin-top: 8px;
        }

        .empty-state {
            text-align: center;
            padding: 60px 20px;
            color: var(--text-light);
        }

        .empty-state i {
            font-size: 48px;
            margin-bottom: 20px;
            color: var(--border-color);
        }

        .empty-state h3 {
            margin-bottom: 10px;
            color: var(--text-dark);
        }

        .empty-state p {
            max-width: 500px;
            margin: 0 auto;
        }

        @media (max-width: 768px) {
            .container {
                padding: 20px 15px;
            }
            
            .header h1 {
                font-size: 1.8rem;
            }
            
            .search-box {
                flex-direction: column;
            }
            
            .search-input {
                border-radius: 10px;
                margin-bottom: 12px;
            }
            
            .search-btn {
                border-radius: 10px;
                padding: 14px;
            }
            
            .file-filter {
                justify-content: center;
            }
            
            .sort-controls {
                justify-content: center;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1><i class="fas fa-search"></i> 服务器检索系统</h1>
            <p>快速查找服务器中的文件和内容信息</p>
        </div>
        
        <div class="search-section">
            <div class="search-box">
                <input type="text" id="searchQuery" class="search-input" placeholder="输入关键词搜索文件或内容...">
                <button id="searchBtn" class="search-btn">
                    <i class="fas fa-search"></i> 搜索
                </button>
            </div>
            
            <div class="search-type-toggle">
                <button id="contentSearchBtn" class="search-type-btn active">
                    <i class="fas fa-file-alt"></i> 内容检索
                </button>
                <button id="fileSearchBtn" class="search-type-btn">
                    <i class="fas fa-folder"></i> 文件查找
                </button>
            </div>
            
            <div id="fileControls" class="file-controls" style="display: none;">
                <div class="file-filter">
                    <button class="filter-btn active" data-type="all">
                        <i class="fas fa-layer-group"></i> 全部
                    </button>
                    <button class="filter-btn" data-type="word">
                        <i class="fas fa-file-word"></i> Word
                    </button>
                    <button class="filter-btn" data-type="excel">
                        <i class="fas fa-file-excel"></i> Excel
                    </button>
                    <button class="filter-btn" data-type="ppt">
                        <i class="fas fa-file-powerpoint"></i> PPT
                    </button>
                    <button class="filter-btn" data-type="pdf">
                        <i class="fas fa-file-pdf"></i> PDF
                    </button>
                    <button class="filter-btn" data-type="image">
                        <i class="fas fa-file-image"></i> 图片
                    </button>
                    <button class="filter-btn" data-type="video">
                        <i class="fas fa-file-video"></i> 视频
                    </button>
                    <button class="filter-btn" data-type="audio">
                        <i class="fas fa-file-audio"></i> 音频
                    </button>
                    <button class="filter-btn" data-type="text">
                        <i class="fas fa-file-lines"></i> 文本
                    </button>
                </div>
                
                <div class="sort-controls">
                    <span class="sort-label">排序方式:</span>
                    <select id="sortField" class="sort-select">
                        <option value="modified_date">修改时间</option>
                        <option value="primary_file">文件路径</option>
                    </select>
                    
                    <div class="sort-order">
                        <button id="sortAsc" class="sort-order-btn" data-order="asc">
                            <i class="fas fa-arrow-up"></i> 升序
                        </button>
                        <button id="sortDesc" class="sort-order-btn active" data-order="desc">
                            <i class="fas fa-arrow-down"></i> 降序
                        </button>
                    </div>
                </div>
            </div>
        </div>
        
        <div id="contentList">
            <div class="empty-state">
                <i class="fas fa-search"></i>
                <h3>开始您的搜索</h3>
                <p>输入关键词并点击搜索按钮，查找服务器中的文件或内容</p>
            </div>
        </div>
        
        <div class="load-more">
            <button id="loadMoreBtn" class="load-more-btn" disabled>
                <i class="fas fa-spinner fa-spin"></i> 加载更多
            </button>
        </div>
        
        <div class="footer">
            <p>2025 检索系统</p>
            <p>内容检索限教学部门 | 技术支持: 电教</p>
            <div class="system-tag">v 0.2</div>
        </div>
    </div>

    <script>
        const pageSize = 10;
        let currentQuery = '';
        let currentScrollId = '';
        let totalResults = 0;
        let loadedResults = 0;
        let isLoading = false;
        let searchType = 'content';
        let fileTypeFilter = 'all';
        let sortField = 'modified_date';
        let sortOrder = 'desc';

        document.addEventListener('DOMContentLoaded', function() {
            // 搜索按钮事件
            document.getElementById('searchBtn').addEventListener('click', performSearch);
            document.getElementById('searchQuery').addEventListener('keypress', function(e) {
                if (e.key === 'Enter') performSearch();
            });
            
            // 加载更多按钮事件
            document.getElementById('loadMoreBtn').addEventListener('click', loadMoreResults);
            
            // 搜索类型切换事件
            document.getElementById('contentSearchBtn').addEventListener('click', function() {
                setSearchType('content');
            });
            document.getElementById('fileSearchBtn').addEventListener('click', function() {
                setSearchType('file');
            });
            
            // 文件类型过滤事件
            document.querySelectorAll('.filter-btn').forEach(btn => {
                btn.addEventListener('click', function() {
                    document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
                    this.classList.add('active');
                    fileTypeFilter = this.dataset.type;
                    if (searchType === 'file') performSearch();
                });
            });
            
            // 排序字段选择事件
            document.getElementById('sortField').addEventListener('change', function() {
                sortField = this.value;
                if (searchType === 'file') performSearch();
            });
            
            // 排序顺序按钮事件
            document.getElementById('sortAsc').addEventListener('click', function() {
                setSortOrder('asc');
            });
            document.getElementById('sortDesc').addEventListener('click', function() {
                setSortOrder('desc');
            });
        });

        function setSearchType(type) {
            searchType = type;
            document.getElementById('contentSearchBtn').classList.toggle('active', type === 'content');
            document.getElementById('fileSearchBtn').classList.toggle('active', type === 'file');
            document.getElementById('fileControls').style.display = type === 'file' ? 'block' : 'none';
            resetSearchState();
            
            // 如果搜索框中有内容，自动执行搜索
            const query = document.getElementById('searchQuery').value;
            if (query) {
                performSearch();
            }
        }

        function setSortOrder(order) {
            sortOrder = order;
            document.getElementById('sortAsc').classList.toggle('active', order === 'asc');
            document.getElementById('sortDesc').classList.toggle('active', order === 'desc');
            if (searchType === 'file') performSearch();
        }

        function resetSearchState() {
            currentQuery = '';
            currentScrollId = '';
            totalResults = 0;
            loadedResults = 0;
            isLoading = false;
            document.getElementById('contentList').innerHTML = '<div class="empty-state"><i class="fas fa-search"></i><h3>开始您的搜索</h3><p>输入关键词并点击搜索按钮，查找服务器中的文件或内容</p></div>';
            const loadMoreBtn = document.getElementById('loadMoreBtn');
            loadMoreBtn.disabled = true;
            loadMoreBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 加载更多';
            document.querySelector('.load-more').style.display = 'none';
        }

        function performSearch() {
            currentQuery = document.getElementById('searchQuery').value;
            if (!currentQuery.trim()) {
                resetSearchState();
                return;
            }
            
            currentScrollId = '';
            loadedResults = 0;
            totalResults = 0;
            isLoading = false;

            const contentList = document.getElementById('contentList');
            contentList.innerHTML = '<div class="empty-state"><i class="fas fa-spinner fa-spin"></i><h3>搜索中...</h3><p>正在检索服务器内容，请稍候</p></div>';
            
            const loadMoreBtn = document.getElementById('loadMoreBtn');
            loadMoreBtn.disabled = true;
            loadMoreBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 加载中';
            document.querySelector('.load-more').style.display = 'none';

            if (searchType === 'content') {
                searchContent(currentQuery);
            } else {
                searchFiles(currentQuery);
            }
        }

        function loadMoreResults() {
            if (isLoading) return;
            
            isLoading = true;
            const loadMoreBtn = document.getElementById('loadMoreBtn');
            loadMoreBtn.disabled = true;
            loadMoreBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 加载中';
            
            if (searchType === 'content') {
                searchContent(currentQuery, currentScrollId);
            } else {
                searchFiles(currentQuery, loadedResults);
            }
        }

        function searchContent(query, scrollId) {
            const endpoint = '/api/search/content';
            const requestData = {
                query: query,
                size: pageSize
            };
            
            if (scrollId) {
                requestData.scroll_id = scrollId;
            }
            
            fetch(endpoint, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(requestData)
            })
            .then(response => response.json())
            .then(data => {
                if (!data.success) {
                    if (data.error === 'scroll_timeout') {
                        document.getElementById('contentList').innerHTML = `
                            <div class="timeout-message">
                                <h3><i class="fas fa-exclamation-triangle"></i> 搜索会话已过期</h3>
                                <p>${data.message}</p>
                                <button class="retry-btn" onclick="performSearch()"><i class="fas fa-redo"></i> 重新搜索</button>
                            </div>`;
                    } else {
                        showError(data.error || '搜索失败');
                    }
                    return;
                }
                
                currentScrollId = data.scroll_id;
                totalResults = data.total;
                loadedResults += data.data.length;
                
                if (scrollId) {
                    appendContentResults(data.data);
                } else {
                    renderContentResults(data.data, data.total);
                }
                
                const hasMore = loadedResults < totalResults;
                const loadMoreBtn = document.getElementById('loadMoreBtn');
                loadMoreBtn.disabled = !hasMore;
                loadMoreBtn.innerHTML = hasMore ? '<i class="fas fa-plus"></i> 加载更多' : '<i class="fas fa-check"></i> 已加载全部';
                document.querySelector('.load-more').style.display = hasMore ? 'block' : 'none';
                isLoading = false;
            })
            .catch(error => {
                showError('搜索请求失败: ' + error.message);
                isLoading = false;
            });
        }

        function searchFiles(query, from = 0) {
            const endpoint = '/api/search/files';
            const requestData = {
                query: query,
                file_type: fileTypeFilter,
                sort_field: sortField,
                sort_order: sortOrder,
                from: from,
                size: pageSize
            };
            
            fetch(endpoint, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(requestData)
            })
            .then(response => response.json())
            .then(data => {
                if (!data.success) {
                    showError(data.error || '文件搜索失败');
                    return;
                }
                
                totalResults = data.total;
                loadedResults = from + data.data.length;
                
                if (from > 0) {
                    appendFileResults(data.data);
                } else {
                    renderFileResults(data.data, data.total);
                }
                
                const hasMore = loadedResults < totalResults;
                const loadMoreBtn = document.getElementById('loadMoreBtn');
                loadMoreBtn.disabled = !hasMore;
                loadMoreBtn.innerHTML = hasMore ? '<i class="fas fa-plus"></i> 加载更多' : '<i class="fas fa-check"></i> 已加载全部';
                document.querySelector('.load-more').style.display = hasMore ? 'block' : 'none';
                isLoading = false;
            })
            .catch(error => {
                showError('文件搜索请求失败: ' + error.message);
                isLoading = false;
            });
        }

        function renderContentResults(results, total) {
            const container = document.getElementById('contentList');
            if (results.length === 0) {
                container.innerHTML = '<div class="empty-state"><i class="fas fa-file-exclamation"></i><h3>未找到匹配内容</h3><p>请尝试其他关键词或调整搜索条件</p></div>';
                document.querySelector('.load-more').style.display = 'none';
                return;
            }
            
            let html = `<div class="result-stats">
                <span>找到 ${total} 个结果</span>
                <span>关键词: <strong>${currentQuery}</strong></span>
            </div>`;
            
            results.forEach((file, index) => {
                html += createResultItemHtml(file, index);
            });
            
            container.innerHTML = html;
            
            const hasMore = loadedResults < totalResults;
            const loadMoreDiv = document.querySelector('.load-more');
            loadMoreDiv.style.display = hasMore ? 'block' : 'none';
        }

        function appendContentResults(results) {
            const container = document.getElementById('contentList');
            if (results.length === 0) return;
            
            let html = '';
            results.forEach((file, index) => {
                html += createResultItemHtml(file, loadedResults - results.length + index);
            });
            
            container.insertAdjacentHTML('beforeend', html);
        }

        function renderFileResults(results, total) {
            const container = document.getElementById('contentList');
            if (results.length === 0) {
                container.innerHTML = '<div class="empty-state"><i class="fas fa-folder-open"></i><h3>未找到匹配文件</h3><p>请尝试其他关键词或调整搜索条件</p></div>';
                document.querySelector('.load-more').style.display = 'none';
                return;
            }
            
            let html = `<div class="result-stats">
                <span>找到 ${total} 个文件</span>
                <span>关键词: <strong>${currentQuery}</strong></span>
            </div>`;
            
            results.forEach(file => {
                html += createFileResultItemHtml(file);
            });
            
            container.innerHTML = html;
        }

        function appendFileResults(results) {
            const container = document.getElementById('contentList');
            if (results.length === 0) return;
            
            let html = '';
            results.forEach(file => {
                html += createFileResultItemHtml(file);
            });
            
            container.insertAdjacentHTML('beforeend', html);
        }

        function createFileResultItemHtml(file) {
            const modifiedDate = formatDate(file.modified_date);
            const fileType = getFileType(file.primary_file);
            const iconInfo = getFileIcon(fileType);
            
            // 处理副本文件显示 - 确保 duplicate_files 是数组
            let duplicateFiles = file.duplicate_files || [];
            if (typeof duplicateFiles === 'string') {
                try {
                    duplicateFiles = JSON.parse(duplicateFiles.replace(/'/g, '"'));
                } catch (e) {
                    console.error('Error parsing duplicate_files:', e);
                    duplicateFiles = [];
                }
            }
            
            let duplicateFilesHtml = '';
            if (duplicateFiles && duplicateFiles.length > 0) {
                duplicateFilesHtml = `
                <div class="duplicate-files-section">
                    <button class="duplicate-toggle" onclick="toggleDuplicateFiles('duplicates-${file.md5_hash}')">
                        <i class="fas fa-copy"></i> 查看副本文件 (${duplicateFiles.length})
                    </button>
                    <div class="duplicate-list" id="duplicates-${file.md5_hash}">
                        <ol>
                            ${duplicateFiles.map(dupFile => `<li>${dupFile}</li>`).join('')}
                        </ol>
                    </div>
                </div>`;
            } else {
                duplicateFilesHtml = `
                <div class="duplicate-files-section">
                    <span class="no-duplicates">无副本文件</span>
                </div>`;
            }
            
            return `
            <div class="file-result-item">
                <div class="file-result-header">
                    <h3 class="file-result-title">
                        <div class="file-icon" style="color: ${iconInfo.color}">
                            <i class="fas ${iconInfo.icon}"></i>
                        </div>
                        ${file.primary_file.split('/').pop()}
                    </h3>
                    <span class="file-tag">${fileType}</span>
                </div>
                
                <div class="file-meta">
                    <div class="meta-item">
                        <i class="fas fa-calendar"></i>
                        <span>${modifiedDate}</span>
                    </div>
                    <div class="meta-item">
                        <i class="fas fa-hashtag"></i>
                        <span>ID: ${file.md5_hash.substring(0, 8)}</span>
                    </div>
                </div>
                
                <div class="file-path">
                    <i class="fas fa-folder"></i> ${file.primary_file}
                </div>
                
                ${duplicateFilesHtml}
            </div>`;
        }

        function toggleDuplicateFiles(duplicateId) {
            const container = document.getElementById(duplicateId);
            const button = container.previousElementSibling;
            const isExpanded = container.classList.contains('expanded');

            if (!isExpanded) {
                container.classList.add('expanded');
                button.innerHTML = '<i class="fas fa-copy"></i> 隐藏副本文件';
            } else {
                container.classList.remove('expanded');
                button.innerHTML = '<i class="fas fa-copy"></i> 查看副本文件';
            }
        }
        
        function formatDate(dateString) {
            if (!dateString) return '未知日期';
            return dateString.split('T')[0]; // 直接按T分割取第一部分
        }
    
        function createResultItemHtml(file, index) {
            const hasHighlights = file.highlight?.content?.length > 0;
            const previewHighlight = hasHighlights ? file.highlight.content[0] : '无匹配内容';
            const modifiedDate = formatDate(file.modified_date);
            
            // 获取文档前200字作为预览
            const previewContent = file.content ? 
                file.content.substring(0, 200) + (file.content.length > 200 ? '...' : '') : 
                '无内容';
            
            // 处理全文内容的高亮
            let fullContent = file.content || '无内容';
            if (currentQuery && fullContent !== '无内容') {
                const queryWords = currentQuery.split(/\s+/).filter(word => word.length > 0);
                queryWords.forEach(word => {
                    const escapedWord = word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
                    const regex = new RegExp(`(${escapedWord})`, 'gi');
                    fullContent = fullContent.replace(regex, (match) => {
                        if (/<em[^>]*>.*<\/em>/i.test(match)) {
                            return match;
                        }
                        return `<em>${match}</em>`;
                    });
                });
            }

            return `
            <div class="result-item">
                <h3><i class="fas fa-file-alt"></i> ${file.filename}</h3>
                <div class="file-meta">
                    <div class="meta-item">
                        <i class="fas fa-calendar"></i>
                        <span>${modifiedDate}</span>
                    </div>
                    <div class="meta-item">
                        <i class="fas fa-database"></i>
                        <span>文档 ID: ${file.md5_hash.substring(0, 8)}</span>
                    </div>
                </div>
                <div class="preview-section" style="margin-bottom: 15px; padding: 15px; background: #f8f9fa; border-radius: 8px; font-size: 15px; line-height: 1.7;">
                    <strong>文档预览:</strong> ${previewContent}
                </div>
                <div class="highlight-section">${previewHighlight}</div>
                
                <div class="toggle-button-wrapper">
                    <button class="expand-toggle" onclick="toggleContent('content-${index}')">
                        <i class="fas fa-chevron-down"></i> 展开全文
                    </button>
                </div>

                <div class="full-content-container" id="content-${index}">
                    <div class="full-content">${fullContent}</div>
                </div>
            </div>`;
        }

        function getFileType(filename) {
            const ext = filename.split('.').pop().toLowerCase();
            if (['doc', 'docx'].includes(ext)) return 'Word 文档';
            if (['xls', 'xlsx'].includes(ext)) return 'Excel 表格';
            if (['ppt', 'pptx'].includes(ext)) return 'PPT 演示';
            if (ext === 'pdf') return 'PDF 文件';
            if (['txt', 'md', 'html', 'htm'].includes(ext)) return '文本文件';
            if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(ext)) return '图片文件';
            if (['mp4', 'mov', 'swf'].includes(ext)) return '视频文件';
            if (['mp3', 'wma', 'amr', 'wma'].includes(ext)) return '音频文件';
            return '未知文件';
        }

        function getFileIcon(fileType) {
            switch(fileType) {
                case 'Word 文档': return { icon: 'fa-file-word', color: '#2b579a' };
                case 'Excel 表格': return { icon: 'fa-file-excel', color: '#217346' };
                case 'PPT 演示': return { icon: 'fa-file-powerpoint', color: '#d24726' };
                case 'PDF 文件': return { icon: 'fa-file-pdf', color: '#f40f02' };
                case '文本文件': return { icon: 'fa-file-lines', color: '#666666' };
                case '图片文件': return { icon: 'fa-file-image', color: '#e67e22' };
                case '视频文件': return { icon: 'fa-file-video', color: '#9b59b6' };
                case '音频文件': return { icon: 'fa-file-audio', color: '#3498db' };
                default: return { icon: 'fa-file', color: '#999999' };
            }
        }

        function showError(message) {
            document.getElementById('contentList').innerHTML = `
                <div class="error-message">
                    <h3><i class="fas fa-exclamation-triangle"></i> 发生错误</h3>
                    <p>${message}</p>
                    <button class="retry-btn" onclick="performSearch()"><i class="fas fa-redo"></i> 重试</button>
                </div>`;
            
            const loadMoreBtn = document.getElementById('loadMoreBtn');
            loadMoreBtn.disabled = true;
            loadMoreBtn.innerHTML = '<i class="fas fa-exclamation-circle"></i> 加载失败';
        }

        function toggleContent(contentId) {
            const container = document.getElementById(contentId);
            const button = container.previousElementSibling.querySelector('.expand-toggle');
            const isExpanded = container.classList.contains('expanded');

            if (!isExpanded) {
                container.classList.add('expanded');
                button.innerHTML = '<i class="fas fa-chevron-up"></i> 收起全文';
            } else {
                container.classList.remove('expanded');
                button.innerHTML = '<i class="fas fa-chevron-down"></i> 展开全文';
            }
        }

        // 全局访问
        window.toggleContent = toggleContent;
        window.performSearch = performSearch;
        window.toggleDuplicateFiles = toggleDuplicateFiles;
    </script>
</body>
</html>